package org.xx.armory.web.tags;

import org.apache.commons.lang3.StringUtils;
import org.xx.armory.web.PathUtils;

import javax.servlet.jsp.PageContext;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

final class TagUtils {
    private static final String ALL_ID_KEY = "__all_id__";

    private TagUtils() {
        throw new UnsupportedOperationException();
    }

    private static String getTheme(
            PageContext context
    ) {
        return Objects.toString(context.getServletContext().getAttribute("__theme__"), "default");
    }

    static String evalThemeUrl(
            PageContext context,
            String first,
            String... more
    ) {
        Objects.requireNonNull(context, "context cannot be null");
        String root = "/themes/" + getTheme(context);
        if (more != null && more.length != 0) {
            String[] more_ = new String[more.length + 1];
            more_[0] = first;
            System.arraycopy(more, 0, more_, 1, more.length);
            return PathUtils.join(root, more_);
        } else {
            return PathUtils.join(root, first);
        }
    }

    static String evalRelThemeUrl(
            PageContext context,
            String first,
            String... more
    ) {
        Objects.requireNonNull(context, "context cannot be null");
        return PathUtils.relative(getPathInfo(context), evalThemeUrl(context, first, more));
    }

    static String evalRelUrl(
            PageContext context,
            String first,
            String... more
    ) {
        Objects.requireNonNull(context, "context cannot be null");
        return PathUtils.relative(getPathInfo(context), PathUtils.join(first, more));
    }

    private static String getPathInfo(PageContext context) {
        Objects.requireNonNull(context, "context cannot be null");
        return Objects.toString(context.getRequest().getAttribute("__original_path__"), "");
    }

    private static TagUtils.IdArray getAllId(PageContext context) {
        Objects.requireNonNull(context, "context cannot be null");
        TagUtils.IdArray allId = (TagUtils.IdArray) context.getAttribute(ALL_ID_KEY);
        if (allId == null) {
            allId = new TagUtils.IdArray();
            context.setAttribute(ALL_ID_KEY, allId);
        }

        return allId;
    }

    static void addId(
            PageContext context,
            String id
    ) {
        if (!StringUtils.isBlank(id)) {
            getAllId(context).add(id);
        }

    }

    private static class IdArray implements Iterable<String> {
        private final List<String> data;

        private IdArray() {
            this.data = new ArrayList<String>();
        }

        void add(String id) {
            Objects.requireNonNull(id, "id cannot be null");
            if (!this.data.contains(id)) {
                this.data.add(id);
            }

        }

        public Iterator<String> iterator() {
            return this.data.iterator();
        }
    }
}

